Money Mom 目前只能記錄「快速記帳」,但是每筆記帳除了金額、標籤以外,還有其它很重要的資訊,像是「時間」、「地點」、「消費類型(收、支)」,因此我們需要實做這個界面來整理快速記帳。
新增記錄的界面,預計會有跟快速記帳一模一樣的欄位,再加上「時間」、「地點」、「消費類型」這三個欄位。
因為新增收支記錄時,還是需要「金額」、「標籤」、「錄音」這三個欄位,只是要再多加上「時間」、「地點」、「消費類型」。
有一個方法是直接複製快速記帳的程式碼,但是身為一個工程師,我們應該無時無刻警惕自己,減少使用 cmd+c 和 cmd+v 的次數。
所以最後我選擇另外一個方法:繼承。
我們可以透過繼承 QuickCreateViewController(快速記帳),再透過 override 新增新的界面元件、排版,就可以有效減少重複的程式碼,如果未來有調整快速記帳頁面的元件時,也可以同步更新這個界面,如下:
class CreateRecordViewController: QuickCreateViewController {
var quickRecord: QuickRecord? {
didSet {
if let quickRecord = quickRecord {
updateUI(with: quickRecord)
}
}
}
convenience init(quickRecord: QuickRecord) {
self.init()
self.quickRecord = quickRecord
updateUI(with: quickRecord)
}
private func updateUI(with quickRecord: QuickRecord) {
amountTextField.text = quickRecord.amount
tags = quickRecord.tags
tagCollectionView.reloadData()
}
}
就如一開始規劃的方式,選擇時間我們可以用一個 UITextField,然後把 inputView 換成 UIDatePicker,如下:
let datePicker: UIDatePicker = {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .dateAndTime
datePicker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
return datePicker
}()
lazy var dateTextField: UITextField = {
let dateTextField = UITextField()
dateTextField.inputView = datePicker
dateTextField.textColor = MMColor.black
dateTextField.leftViewMode = .always
dateTextField.leftView = {
let leftViewLabel = UILabel()
leftViewLabel.text = "日期:"
leftViewLabel.sizeToFit()
leftViewLabel.textColor = MMColor.black
return leftViewLabel
}()
return dateTextField
}()
@objc func datePickerValueChanged() {
setDateTextFieldText(with: datePicker.date)
}
private func setDateTextFieldText(with date: Date) {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
formatter.timeZone = TimeZone.current
dateTextField.text = formatter.string(from: date)
}
理想的設計,應該是在新增快速記帳時,就先把使用者當下的位置記錄下來,然後新增收支記錄時,就可以預先顯示當時的位置,使用者要編輯的時候,會跳出以該點為中心的地圖,讓使用者選擇地點(也可以透過搜尋店家名稱的方式),在此先用一個簡單的 UITextField 代替,之後再接入 Google Map。
lazy var locationTextField: UITextField = {
let locationTextField = UITextField()
locationTextField.textColor = MMColor.black
locationTextField.leftViewMode = .always
locationTextField.leftView = {
let leftViewLabel = UILabel()
leftViewLabel.text = "地點:"
leftViewLabel.sizeToFit()
leftViewLabel.textColor = MMColor.black
return leftViewLabel
}()
return locationTextField
}()
前面規劃時以為只有 UISwitch,本來要自己做兩個按鈕取代 UISwitch,結果後來發現還有 UISegmentedControl 可以用,Apple 好貼心啊!
lazy var transactionTypeSegmentedControl: UISegmentedControl = {
let transactionTypeSegmentedControl = UISegmentedControl()
transactionTypeSegmentedControl.tintColor = MMColor.black
transactionTypeSegmentedControl.insertSegment(withTitle: "收入", at: 0, animated: false)
transactionTypeSegmentedControl.insertSegment(withTitle: "支出", at: 1, animated: false)
transactionTypeSegmentedControl.addTarget(self, action: #selector(transactionTypeChanged), for: .valueChanged)
return transactionTypeSegmentedControl
}()
@objc func transactionTypeChanged() {
if transactionTypeSegmentedControl.selectedSegmentIndex == 0 {
transactionTypeSegmentedControl.tintColor = MMColor.green
transactionTypeSegmentedControl.setTitleTextAttributes([
NSAttributedStringKey.foregroundColor: MMColor.black
], for: .normal)
transactionTypeSegmentedControl.setTitleTextAttributes([
NSAttributedStringKey.foregroundColor: MMColor.black
], for: .selected)
} else {
transactionTypeSegmentedControl.tintColor = MMColor.red
transactionTypeSegmentedControl.setTitleTextAttributes([
NSAttributedStringKey.foregroundColor: MMColor.black
], for: .normal)
transactionTypeSegmentedControl.setTitleTextAttributes([
NSAttributedStringKey.foregroundColor: MMColor.white
], for: .selected)
}
}
這個顏色、排版……「界面重構」的優先度越來越高了。
程式碼如下(GitHub):
下一篇會專心處理 Core Data 的功能,使用者按下右上角儲存後,原本的快速記帳記錄會被設定為「已整理」,然後新的收支記錄會被儲存起來。